﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;
using IssueTracker.Business.BO;
using IssueTracker.Business.Entity;

namespace IssueTracker.Service
{
    [ServiceBehavior(UseSynchronizationContext = false,
    ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.PerCall)]
    public class IssueTrackerService: IIssueTrackerService
    {

        #region ProjectBO 

        public Project CreateProject(Project project)
        {
            ProjectBO bo = new ProjectBO();
            
            return bo.AddNew(project);
        }

        public Project UpdateProject(Project project)
        {
            ProjectBO bo = new ProjectBO();

            return bo.UpdateProject(project);
        }

        public void DeleteProject(Project project)
        {
            ProjectBO bo = new ProjectBO();

            bo.DeleteProject(project);
        }

        public IEnumerable<Project> ListProjects()
        {
            ProjectBO bo = new ProjectBO();

            return bo.ListProjects();

        }

        public Project GetProject(int id)
        {
            ProjectBO bo = new ProjectBO();

            return bo.GetProject(id);
        }

        #endregion
                
        #region ProjectMemberBO

        public ProjectMember CreateProjectMember(ProjectMember entity)
        {
            ProjectMemberBO bo = new ProjectMemberBO();

            return bo.AddNew(entity);
        }

        public ProjectMember UpdateProjectMember(ProjectMember entity)
        {
            ProjectMemberBO bo = new ProjectMemberBO();

            return bo.UpdateProjectMember(entity);
        }

        public void DeleteProjectMember(ProjectMember entity)
        {
            ProjectMemberBO bo = new ProjectMemberBO();

            bo.DeleteProjectMember(entity);
        }

        public IEnumerable<ProjectMember> ListProjectMembers()
        {
            ProjectMemberBO bo = new ProjectMemberBO();

            return bo.ListProjectMembers();

        }

        public ProjectMember GetProjectMember(int id)
        {
            ProjectMemberBO bo = new ProjectMemberBO();

            return bo.GetProjectMember(id);
        }

        #endregion

        #region ProjectCustomTypeBO Implementation

        public ProjectCustomType CreateProjectCustomType(ProjectCustomType entity)
        {
            ProjectCustomTypeBO bo = new ProjectCustomTypeBO();

            return bo.AddNew(entity);
        }

        public ProjectCustomType UpdateProjectCustomType(ProjectCustomType entity)
        {
            ProjectCustomTypeBO bo = new ProjectCustomTypeBO();

            return bo.UpdateProjectCustomType(entity);
        }

        public void DeleteProjectCustomType(ProjectCustomType entity)
        {
            ProjectCustomTypeBO bo = new ProjectCustomTypeBO();

            bo.DeleteProjectCustomType(entity);
        }

        public IEnumerable<ProjectCustomType> ListProjectCustomTypes()
        {
            ProjectCustomTypeBO bo = new ProjectCustomTypeBO();

            return bo.ListProjectCustomTypes();

        }

        public ProjectCustomType GetProjectCustomType(int id)
        {
            ProjectCustomTypeBO bo = new ProjectCustomTypeBO();

            return bo.GetProjectCustomType(id);
        }

        #endregion
        
        #region ProjectCustomTypeColumnBO Implementation

        public ProjectCustomTypeColumn CreateProjectCustomTypeColumn(ProjectCustomTypeColumn entity)
        {
            ProjectCustomTypeColumnBO bo = new ProjectCustomTypeColumnBO();

            return bo.AddNew(entity);
        }

        public ProjectCustomTypeColumn UpdateProjectCustomTypeColumn(ProjectCustomTypeColumn entity)
        {
            ProjectCustomTypeColumnBO bo = new ProjectCustomTypeColumnBO();

            return bo.UpdateProjectCustomTypeColumn(entity);
        }

        public void DeleteProjectCustomTypeColumn(ProjectCustomTypeColumn entity)
        {
            ProjectCustomTypeColumnBO bo = new ProjectCustomTypeColumnBO();

            bo.DeleteProjectCustomTypeColumn(entity);
        }

        public IEnumerable<ProjectCustomTypeColumn> ListProjectCustomTypeColumns()
        {
            ProjectCustomTypeColumnBO bo = new ProjectCustomTypeColumnBO();

            return bo.ListProjectCustomTypeColumns();

        }

        public ProjectCustomTypeColumn GetProjectCustomTypeColumn(int id)
        {
            ProjectCustomTypeColumnBO bo = new ProjectCustomTypeColumnBO();

            return bo.GetProjectCustomTypeColumn(id);
        }

        #endregion

        #region IssueBO Implementation

        public Issue CreateIssue(Issue entity)
        {
            IssueBO bo = new IssueBO();

            return bo.AddNew(entity);
        }

        public Issue UpdateIssue(Issue entity)
        {
            IssueBO bo = new IssueBO();

            return bo.UpdateIssue(entity);
        }

        public Issue UpdateWorkflowStatus(string issueId, string action)
        {
            IssueBO bo = new IssueBO();

            Issue returnIssue = bo.GetIssue(new Guid(issueId));

            switch (action)
            {
                case "ValidateIssue":
                    returnIssue.CurrentStateName = "Pending Solution";
                    break;
                case "RejectIssue":
                    returnIssue.CurrentStateName = "Issue Closed";
                    break;
                case "SolutionCompleted":
                    returnIssue.CurrentStateName = "Pending Testing";
                    break;
                case "SolutionAccepted":
                    returnIssue.CurrentStateName = "Issue Closed";
                    break;
                case "SolutionRejected":
                    returnIssue.CurrentStateName = "Pending Solution";
                    break;
            }

            return bo.UpdateIssue(returnIssue);
        }

        public void DeleteIssue(Issue entity)
        {
            IssueBO bo = new IssueBO();

            bo.DeleteIssue(entity);
        }

        public IEnumerable<Issue> ListIssues()
        {
            IssueBO bo = new IssueBO();

            return bo.ListIssues();

        }

        public IEnumerable<Issue> SearchIssues(Issue issue)
        {
            IssueBO bo = new IssueBO();

            return bo.SearchIssues(issue);

        }


        public Issue GetIssue(System.Guid id)
        {
            IssueBO bo = new IssueBO();

            return bo.GetIssue(id);
        }

        public Issue GetIssueByWorkflowInstanceid(System.Guid workflowInstanceId)
        {
            IssueBO bo = new IssueBO();

            return bo.ListIssueByWorfklowInstanceId(workflowInstanceId);
        }

        public IEnumerable<Issue> TaskList(string userName, string stateName)
        {
            IssueBO bo = new IssueBO();

            return bo.TaskList(userName, stateName);
        }

        #endregion



        #region IssueTaskBO Implementation

        public IssueTask CreateIssueTask(IssueTask entity)
        {
            IssueTaskBO bo = new IssueTaskBO();

            return bo.AddNew(entity);
        }

        public IssueTask UpdateIssueTask(IssueTask entity)
        {
            IssueTaskBO bo = new IssueTaskBO();

            return bo.UpdateIssueTask(entity);
        }

        public void DeleteIssueTask(IssueTask entity)
        {
            IssueTaskBO bo = new IssueTaskBO();

            bo.DeleteIssueTask(entity);
        }

        public IEnumerable<IssueTask> ListIssueTasks()
        {
            IssueTaskBO bo = new IssueTaskBO();

            return bo.ListIssueTasks();

        }

        public IssueTask GetIssueTask(System.Guid id)
        {
            IssueTaskBO bo = new IssueTaskBO();

            return bo.GetIssueTask(id);
        }

        #endregion



        #region IssueAttachmentBO Implementation

        public IssueAttachment CreateIssueAttachment(IssueAttachment entity)
        {
            IssueAttachmentBO bo = new IssueAttachmentBO();

            return bo.AddNew(entity);
        }

        public IssueAttachment UpdateIssueAttachment(IssueAttachment entity)
        {
            IssueAttachmentBO bo = new IssueAttachmentBO();

            return bo.UpdateIssueAttachment(entity);
        }

        public void DeleteIssueAttachment(IssueAttachment entity)
        {
            IssueAttachmentBO bo = new IssueAttachmentBO();

            bo.DeleteIssueAttachment(entity);
        }

        public IEnumerable<IssueAttachment> ListIssueAttachments()
        {
            IssueAttachmentBO bo = new IssueAttachmentBO();

            return bo.ListIssueAttachments();

        }

        public IssueAttachment GetIssueAttachment(System.Guid id)
        {
            IssueAttachmentBO bo = new IssueAttachmentBO();

            return bo.GetIssueAttachment(id);
        }

        #endregion



        #region IssueCustomTypeValueBO Implementation

        public IssueCustomTypeValue CreateIssueCustomTypeValue(IssueCustomTypeValue entity)
        {
            IssueCustomTypeValueBO bo = new IssueCustomTypeValueBO();

            return bo.AddNew(entity);
        }

        public IssueCustomTypeValue UpdateIssueCustomTypeValue(IssueCustomTypeValue entity)
        {
            IssueCustomTypeValueBO bo = new IssueCustomTypeValueBO();

            return bo.UpdateIssueCustomTypeValue(entity);
        }

        public void DeleteIssueCustomTypeValue(IssueCustomTypeValue entity)
        {
            IssueCustomTypeValueBO bo = new IssueCustomTypeValueBO();

            bo.DeleteIssueCustomTypeValue(entity);
        }

        public IEnumerable<IssueCustomTypeValue> ListIssueCustomTypeValues()
        {
            IssueCustomTypeValueBO bo = new IssueCustomTypeValueBO();

            return bo.ListIssueCustomTypeValues();

        }

        public IssueCustomTypeValue GetIssueCustomTypeValue(System.Guid id)
        {
            IssueCustomTypeValueBO bo = new IssueCustomTypeValueBO();

            return bo.GetIssueCustomTypeValue(id);
        }

        #endregion



        #region IssueWfHistoryBO Implementation

        public IssueWfHistory CreateIssueWfHistory(IssueWfHistory entity)
        {
            IssueWfHistoryBO bo = new IssueWfHistoryBO();

            return bo.AddNew(entity);
        }

        public IssueWfHistory UpdateIssueWfHistory(IssueWfHistory entity)
        {
            IssueWfHistoryBO bo = new IssueWfHistoryBO();

            return bo.UpdateIssueWfHistory(entity);
        }

        public void DeleteIssueWfHistory(IssueWfHistory entity)
        {
            IssueWfHistoryBO bo = new IssueWfHistoryBO();

            bo.DeleteIssueWfHistory(entity);
        }

        public IEnumerable<IssueWfHistory> ListIssueWfHistories()
        {
            IssueWfHistoryBO bo = new IssueWfHistoryBO();

            return bo.ListIssueWfHistorys();

        }

        public IssueWfHistory GetIssueWfHistory(System.Guid id)
        {
            IssueWfHistoryBO bo = new IssueWfHistoryBO();

            return bo.GetIssueWfHistory(id);
        }

        #endregion


        #region IIssueTrackerService Members


        public IEnumerable<ProjectCustomType> ListProjectCustomTypesByRef(int reference)
        {
            ProjectCustomTypeBO bo = new ProjectCustomTypeBO();

            return bo.ListProjectCustomTypesByRef(reference);
        }

        public IEnumerable<ProjectCustomTypeColumn> ListProjectCustomTypeColumnsByRef(int reference)
        {
            ProjectCustomTypeColumnBO bo = new ProjectCustomTypeColumnBO();

            return bo.ListProjectCustomTypeColumnsByRef(reference);
        }

        public IEnumerable<ProjectMember> ListProjectMembersByRef(int reference)
        {
            ProjectMemberBO bo = new ProjectMemberBO();

            return bo.ListProjectMembersByRef(reference);
        }

        public IEnumerable<IssueAttachment> ListIssueAttachmentsByRef(Guid reference)
        {
            IssueAttachmentBO bo = new IssueAttachmentBO();

            return bo.ListIssueAttachementsByRef(reference);
        }

        public IEnumerable<IssueCustomTypeValue> ListIssueCustomTypeValuesByRef(Guid reference)
        {
            IssueCustomTypeValueBO bo = new IssueCustomTypeValueBO();

            return bo.ListIssueCustomTypeValuesByRef(reference);
        }

        public IEnumerable<IssueTask> ListIssueTasksByRef(Guid reference)
        {
            IssueTaskBO bo = new IssueTaskBO();

            return bo.ListIssueTasksByRef(reference);
        }

        public IEnumerable<IssueWfHistory> ListIssueWfHistoriesByRef(Guid reference)
        {
            IssueWfHistoryBO bo = new IssueWfHistoryBO();

            return bo.ListIssueWfHistoriesByRef(reference);
        }

        #endregion

        #region "helper methods"
        public IDictionary<string, string> GetEventList(string currentStateName)
        {
            //TODO: Haven't figure out to do it dynamically, hard code first
            //http://dotnetperls.com/Content/Dictionary-Keys.aspx for how to use IDictionary object
            //It is a value pair of Action Name and the Workflow Activity to trigger
            IDictionary<string, string> returnEventList = new Dictionary<string, string>();

            switch (currentStateName)
            {
                case "Pending Approval":
                    returnEventList.Add("Approval", "IssueApproved");
                    returnEventList.Add("Reject", "IssueRejected");
                    break;
                case "Pending Solution":
                    returnEventList.Add("Complete", "SolutionCompleted");
                    break;

                case "Pending Testing":
                    returnEventList.Add("Accept", "SolutionAccepted");
                    returnEventList.Add("Reject", "SolutionRejected");
                    break;
            }

            return returnEventList;
        }
        #endregion
    }
}
